home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Clock / Sources / Part.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  12.6 KB  |  443 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Part.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef PART_H
  11. #include "Part.h"
  12. #endif
  13.  
  14. #ifndef DEFINES_K
  15. #include "Defines.k"
  16. #endif
  17.  
  18. #ifndef BINDING_K
  19. #include "Binding.k"
  20. #endif
  21.  
  22. #ifndef FRAME_H
  23. #include "Frame.h"
  24. #endif
  25.  
  26. #ifndef CONTENT_H
  27. #include "Content.h"
  28. #endif
  29.  
  30. #ifndef VIEW_H
  31. #include "View.h"
  32. #endif
  33.  
  34. #ifndef DIALOG_H
  35. #include "Dialog.h"
  36. #endif
  37.  
  38. // ----- Framework Layer -----
  39.  
  40. #ifndef FWPRTITE_H
  41. #include "FWPrtIte.h"
  42. #endif
  43.  
  44. #ifndef FWABOUT_H
  45. #include "FWAbout.h"
  46. #endif
  47.  
  48. #ifndef FWITERS_H
  49. #include "FWIters.h"
  50. #endif
  51.  
  52. #ifndef FWIDLE_H
  53. #include "FWIdle.h"
  54. #endif
  55.  
  56. // ----- OS Layer -----
  57.  
  58. #ifndef FWMENU_H
  59. #include "FWMenu.h"
  60. #endif
  61.  
  62. #ifndef FWODMISC_H
  63. #include "FWODMisc.h"
  64. #endif
  65.  
  66. #ifndef FWEVENT_H
  67. #include "FWEvent.h"
  68. #endif
  69.  
  70. #ifndef FWCFMRES_H
  71. #include "FWCFMRes.h"
  72. #endif
  73.  
  74. #ifndef FWRESTYP_H
  75. #include "FWResTyp.h"
  76. #endif
  77.  
  78. // ----- Foundation Layer -----
  79.  
  80. #ifndef FWMEMMGR_H
  81. #include "FWMemMgr.h"
  82. #endif
  83.  
  84. // ----- OpenDoc Includes -----
  85.  
  86. #ifndef SOM_Module_OpenDoc_StdProps_defined
  87. #include <StdProps.xh>
  88. #endif
  89.  
  90. // ----- Macintosh Includes -----
  91.  
  92. #if defined(FW_BUILD_MAC) && !defined(__SOUND__)
  93. #include <Sound.h>
  94. #endif
  95.  
  96. //========================================================================================
  97. // Runtime information
  98. //========================================================================================
  99.  
  100. #ifdef FW_BUILD_MAC
  101. #pragma segment odfclock
  102. #endif
  103.  
  104. //========================================================================================
  105. //    Globals
  106. //========================================================================================
  107.  
  108. //========================================================================================
  109. // Constants
  110. //========================================================================================
  111.  
  112. const short kClockIdleFreq = 15;
  113.  
  114. //========================================================================================
  115. //    Class CClockPart
  116. //========================================================================================
  117.  
  118. FW_DEFINE_AUTO(CClockPart)
  119.     
  120. //----------------------------------------------------------------------------------------
  121. // CClockPart::CClockPart
  122. //----------------------------------------------------------------------------------------
  123. CClockPart::CClockPart(ODPart* odPart) :
  124.     FW_CPart(odPart, FW_gInstance, kPartInfoID),
  125.     fLastTime(FW_CTime::GetCurrentTime()),
  126.     fClockContent(NULL),
  127.     fLockIdle(FALSE),
  128.     fIdler(NULL),
  129. #ifdef FW_BUILD_MAC
  130.     fChimeSound(NULL),
  131.     fTickSound(NULL),
  132. #endif
  133.     fUseContainerColor(FALSE)
  134. {
  135.     FW_END_CONSTRUCTOR
  136. }
  137.  
  138. //----------------------------------------------------------------------------------------
  139. // CClockPart::~CClockPart
  140. //----------------------------------------------------------------------------------------
  141. CClockPart::~CClockPart()
  142. {
  143.     FW_START_DESTRUCTOR
  144.     
  145.     delete fIdler;
  146.     
  147. #ifdef FW_BUILD_MAC
  148.     if (fChimeSound)
  149.         FW_CMemoryManager::FreeSystemHandle((FW_PlatformHandle)fChimeSound);
  150.     fChimeSound = NULL;
  151.  
  152.     if (fTickSound)
  153.         FW_CMemoryManager::FreeSystemHandle((FW_PlatformHandle)fTickSound);
  154.     fTickSound = NULL;
  155. #endif
  156. }
  157.  
  158. //----------------------------------------------------------------------------------------
  159. // CClockPart::Initialize
  160. //----------------------------------------------------------------------------------------
  161.  
  162. void CClockPart::Initialize(Environment* ev, ODStorageUnit* storageUnit, FW_Boolean fromStorage)
  163. {
  164.     FW_CPart::Initialize(ev, storageUnit, fromStorage);
  165.     
  166.     // ----- Register Presentation -----
  167.     fAnalogPresentation = RegisterPresentation(ev, kAnalogPresentation, TRUE, kAnalogClockView, kAnalogClockViewRoot);
  168.     fDigitalPresentation = RegisterPresentation(ev, kDigitalPresentation, FALSE, kDigitalClockView, kDigitalClockViewRoot);
  169.     fClockSettingsPresentation = RegisterPresentation(ev, kClockSettingsPresentation, false, kClockSettingsDialog, kClockSettingsDialog);
  170.             
  171.     // We instantiate a FW_CToggleItem from a stream so we must 
  172.     // keep it from being deadstripped.
  173.     FW_DO_NOT_DEAD_STRIP(FW_CToggleItem);
  174.  
  175. #ifdef FW_BUILD_MAC    
  176.     FW_PSharedLibraryResourceFile resFile(ev);
  177.     
  178.     // ----- Get default clock sounds
  179.     fChimeSound = ::GetResource(soundListRsrc, kClockChime);
  180.     ::DetachResource(fChimeSound);
  181.     
  182.     fTickSound = ::GetResource(soundListRsrc, kClockTick);
  183.     ::DetachResource(fTickSound);
  184. #endif
  185.  
  186.     // ----- Create the Idler -----
  187.     fIdler = FW_NEW(FW_CIdler, (this, kClockIdleFreq));
  188.     fIdler->RegisterIdle(ev);
  189. }
  190.  
  191. //------------------------------------------------------------------------------
  192. // CClockPart::NewPartContent
  193. //------------------------------------------------------------------------------
  194.  
  195. FW_CContent* CClockPart::NewPartContent(Environment* ev)
  196. {
  197.     fClockContent = FW_NEW(CClockContent, (ev, this));
  198.     return fClockContent;
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // CClockPart::NewFrame
  203. //----------------------------------------------------------------------------------------
  204.  
  205. FW_CFrame* CClockPart::NewFrame(Environment* ev, ODFrame* odFrame, FW_CPresentation* presentation, FW_Boolean fromStorage)
  206. {
  207.     FW_UNUSED(fromStorage);
  208.  
  209.     if (presentation == fClockSettingsPresentation)
  210.     {
  211.         return FW_NEW(CClockSettingsDialogFrame, (ev, odFrame, presentation, this));
  212.     }
  213.  
  214.     return FW_NEW(CClockFrame, (ev, odFrame, presentation, this, fClockContent));
  215. }
  216.  
  217. //----------------------------------------------------------------------------------------
  218. // CClockPart::Tick
  219. //----------------------------------------------------------------------------------------
  220.  
  221. short CClockPart::Tick(Environment* ev, FW_CPresentation* presentation, const FW_CTime& currentTime)
  222. {
  223.     short frameCount = 0;
  224.         
  225.     // Update all the display frames of the same type
  226.     FW_CPresentationFrameIterator iter(ev, presentation);
  227.     for (CClockFrame *clockFrame = (CClockFrame*)iter.First(ev); iter.IsNotComplete(ev); clockFrame = (CClockFrame*)iter.Next(ev))
  228.     {
  229.         if ((!clockFrame->IsInLimbo(ev)))
  230.         {
  231.             frameCount++;
  232.             if (clockFrame->GetViewType(ev) == FW_CPart::fgViewAsFrameToken)
  233.             {
  234.                 CClockView* clockView = clockFrame->GetClockView(ev);
  235.                 if (clockView)
  236.                     clockView->UpdateClock(ev, currentTime);
  237.             }
  238.         }
  239.     }
  240.     
  241.     return frameCount;
  242. }
  243.  
  244. //----------------------------------------------------------------------------------------
  245. // CClockPart::DoIdle
  246. //----------------------------------------------------------------------------------------
  247.  
  248. FW_Handled CClockPart::DoIdle(Environment* ev, const FW_CNullEvent& theNullEvent)
  249. {
  250.     FW_UNUSED(theNullEvent);
  251.  
  252.     if (fLockIdle)
  253.         return FW_kHandled;
  254.         
  255.     FW_CTime currentTime = FW_CTime::GetCurrentTime() + fClockContent->GetTimeOffset();
  256.      if (fLastTime != currentTime)
  257.     {
  258.         short frameCount = 0;
  259.         
  260.         frameCount = Tick(ev, fAnalogPresentation, currentTime);    
  261.         frameCount += Tick(ev, fDigitalPresentation, currentTime);
  262.         
  263.         if (frameCount > 0)
  264.         {
  265.             if (fClockContent->HasTickSound())
  266.                 this->PlayTickSound();
  267.             if (fClockContent->HasChimeSound() && (currentTime.GetMinute() == 0) && (currentTime.GetSecond() == 0))
  268.                 this->PlayChimeSound();
  269.         }
  270.         
  271.         fLastTime = currentTime;
  272.     }
  273.     return FW_kHandled;
  274. }
  275.  
  276. //----------------------------------------------------------------------------------------
  277. // CClockPart::DoAbout
  278. //----------------------------------------------------------------------------------------
  279.  
  280. FW_Handled CClockPart::DoAbout(Environment* ev)
  281. {
  282.     ::FW_About(ev, this, kAbout);
  283.     
  284.     return FW_kHandled;
  285. }
  286.  
  287. //----------------------------------------------------------------------------------------
  288. // CClockPart::SynchContainingPartProperties
  289. //----------------------------------------------------------------------------------------
  290.  
  291. void CClockPart::SynchContainingPartProperties(Environment* ev, FW_CPresentation* presentation)
  292. {
  293.     FW_CPresentationFrameIterator iter(ev, presentation);
  294.     for (CClockFrame* frame = (CClockFrame*)iter.First(ev); iter.IsNotComplete(ev); frame = (CClockFrame*)iter.Next(ev))
  295.     {
  296.         frame->SynchContainingPartProperties(ev);
  297.     }
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. // CClockPart::DoMenu
  302. //----------------------------------------------------------------------------------------
  303.  
  304. FW_Handled CClockPart::DoMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
  305. {
  306.     FW_Handled menuHandled = FW_kHandled;
  307.     
  308.     switch (theMenuEvent.GetCommandID(ev))
  309.     {
  310.         case cClockSoundsTick:
  311.             fClockContent->ToggleTickSound();
  312.             this->Changed(ev);
  313.             break;
  314.  
  315.         case cClockSoundsChime:
  316.             fClockContent->ToggleChimeSound();
  317.             this->Changed(ev);
  318.             break;
  319.                 
  320.         case cClockSettings:
  321.             OpenClockSettingsDialog(ev);
  322.             break;
  323.  
  324.         case cClockUseContainerColor:
  325.             {
  326.                 fUseContainerColor = !fUseContainerColor;
  327.                 SynchContainingPartProperties(ev, fAnalogPresentation);
  328.                 SynchContainingPartProperties(ev, fDigitalPresentation);
  329.             }
  330.             break;
  331.  
  332.         default:
  333.             menuHandled = FW_kNotHandled;
  334.     }            
  335.     
  336.     return menuHandled;
  337. }
  338.  
  339. //----------------------------------------------------------------------------------------
  340. // CClockPart::DoAdjustMenus
  341. //----------------------------------------------------------------------------------------
  342.  
  343. FW_Handled CClockPart::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  344. {
  345.     if (hasMenuFocus)
  346.     {    
  347.         menuBar->EnableAndCheckCommand(ev, cClockSoundsTick, TRUE, fClockContent->HasTickSound());
  348.         menuBar->EnableAndCheckCommand(ev, cClockSoundsChime, TRUE, fClockContent->HasChimeSound());
  349.         
  350.         menuBar->EnableCommand(ev, cClockSettings, true);
  351.  
  352.         menuBar->EnableAndCheckCommand(ev, cClockUseContainerColor, !isRoot, fUseContainerColor);
  353.     }
  354.         
  355.     return FW_kNotHandled;
  356. }
  357.  
  358. //----------------------------------------------------------------------------------------
  359. // CClockPart::PlayTickSound
  360. //----------------------------------------------------------------------------------------
  361.  
  362. void CClockPart::PlayTickSound()
  363. {
  364. #ifdef FW_BUILD_MAC
  365.     ::SndPlay(NULL, (SndListHandle)fTickSound, TRUE);
  366. #endif
  367. #ifdef FW_BUILD_WIN
  368.     ::MessageBeep(-1);
  369. #endif
  370. }
  371.  
  372. //----------------------------------------------------------------------------------------
  373. // CClockPart::PlayChimeSound
  374. //----------------------------------------------------------------------------------------
  375.  
  376. void CClockPart::PlayChimeSound()
  377. {
  378. #ifdef FW_BUILD_MAC
  379.     ::SndPlay(NULL, (SndListHandle)fChimeSound, TRUE);
  380. #endif
  381. #ifdef FW_BUILD_WIN
  382.     ::MessageBeep(-1);
  383. #endif
  384. }
  385.  
  386. //----------------------------------------------------------------------------------------
  387. // CClockPart::SwitchPresentation
  388. //----------------------------------------------------------------------------------------
  389.  
  390. FW_CPresentation* CClockPart::SwitchPresentation(FW_CPresentation* currentPresentation) const
  391. {
  392.     if (currentPresentation == fAnalogPresentation)
  393.         return fDigitalPresentation;
  394.     else
  395.         return fAnalogPresentation;
  396. }
  397.  
  398. //----------------------------------------------------------------------------------------
  399. // CClockPart::OpenClockSettingsDialog
  400. //----------------------------------------------------------------------------------------
  401.  
  402. void CClockPart::OpenClockSettingsDialog(Environment* ev)
  403. {
  404.     FW_CPoint position(FW_kZeroPoint);
  405.     FW_CPoint size(FW_IntToFixed(320), FW_IntToFixed(130));
  406.     FW_WindowStyle style = FW_kStandardDialogPosition | FW_kHasCaption;
  407.  
  408.     FW_CString title;
  409.     FW_PSharedLibraryResourceFile resFile(ev);
  410.     ::FW_LoadStringByID(ev, resFile, kClockStrings, FW_kMultiStringRes, kClockSettingsTitleString, title);
  411.  
  412.     CClockSettingsDialogFrame* dialog = (CClockSettingsDialogFrame*) FW_CDialogFrame::NewAndShowModalDialog(ev, 
  413.                             this,                        // Your part
  414.                             fClockSettingsPresentation, // Used in NewFrame
  415.                             size,                         // Window size
  416.                             position,                     // Window position
  417.                             style,                        // Make dialog moveable
  418.                             title);                        // Title for moveable dialog
  419. }
  420.  
  421. //----------------------------------------------------------------------------------------
  422. // CClockPart::SetClock
  423. //----------------------------------------------------------------------------------------
  424.  
  425. void CClockPart::SetClock(Environment* ev, long hourOffset, const FW_CString& faceString)
  426. {
  427.     // FW_CTimeSpan(long days, short hours, short minutes, short seconds);
  428.     FW_CTimeSpan offset(0, hourOffset, 0, 0);
  429.     fClockContent->SetTimeOffset(offset);
  430.     fClockContent->SetFaceString(faceString);
  431.  
  432.     // Notify interested parties of change
  433.     this->Changed(ev);
  434.     fAnalogPresentation->ContentUpdated(ev);
  435.     fDigitalPresentation->ContentUpdated(ev);
  436.  
  437.     // Redraw the analog clock
  438.     fAnalogPresentation->Invalidate(ev);
  439.  
  440.     // Don't need to redraw the digital clock since it will update in a second
  441. //    fDigitalPresentation->Invalidate(ev);
  442. }
  443.